#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <chrono>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "json.hpp"
#include "DataBase.hpp"

//!todo 完善客户端逻辑

//记录当前系统登录的用户信息
MySQLTable::User g_currentUser;
//记录当前用户的群组列表信息
std::vector<struct MySQLTable::AllGroup> g_currentUserGroupList;
std::vector<struct MySQLTable::User> g_currentUserFriendList;
//显示当前用户的基本信息
void showCurrentUserData();


//接收线程
void readTaskHandler(int clientfd);
//获取系统时间
std::string getCurrentTime();
//住聊天页面程序
void mainMenu();

int main(int argc,char** argv) {
    if(argc<3){
        std::cerr<<"command invalid! example: ./client 127.0.0.1 6000"<<std::endl;
        exit(-1);
    }
    //拿到输入的ip地址和端口
    char* ip = argv[1];
    uint16_t port = atoi(argv[2]);

    //创建client的socket
    int clientfd = socket(AF_INET,SOCK_STREAM,0);
    if(clientfd == -1){
        std::cerr<<"fail to create socket"<<std::endl;
        exit(-1);
    }

    //填写client需要联机的server信息ip+port
    sockaddr_in server;
    memset(&server,0,sizeof(sockaddr_in));
    server.sin_family=AF_INET;
    server.sin_port=htons(port);
    server.sin_addr.s_addr= inet_addr(ip);

    //连接服务器
    if(-1 == connect(clientfd,(sockaddr*)&server,sizeof(sockaddr_in))){
        std::cerr<<"fail to connect server"<<std::endl;
        close(clientfd);
        exit(-1);
    }

    //死循环，这里负责发送，线程负责接受
    for(;;){
        std::cout<<"============================="<<std::endl;
        std::cout<<"1. logic"<<std::endl;
        std::cout<<"2. register"<<std::endl;
        std::cout<<"3. quit"<<std::endl;
        std::cout<<"============================="<<std::endl;
        std::cout<<"choice:";
        int choice = 0;
        std::cin>>choice;
        std::cin.get();//读取缓冲区的回车

        switch ((choice)) {
            case 1:{
                int id = 0;
                char pwd[50]={0};
                std::cout<<"userID:";
                std::cin>>id;
                std::cin.get();
                std::cout<<"password:";
                std::cin.getline(pwd,50);

                nlohmann::json js;
                js["msgID"]=ReqType::Logic;
                js["id"]=id;
                js["password"]=pwd;
                std::string request = js.dump();
                break;
            }
            case 2:{
                char name[50]={0};
                char pwd[50]={0};
                std::cout<<"user name:";
                std::cin.getline(name,50);
                std::cout<<"user pwd:";
                std::cin.getline(pwd,50);

                nlohmann::json js;
                js["msgID"] = ReqType::Register;
                js["name"] = name;
                js["password"] = pwd;
                std::string request = js.dump();

                int len = send(clientfd,request.c_str(),strlen(request.c_str())+1,0);
                if(len<0){
                    std::cerr<<"fail to send :"<<request<<std::endl;
                }else{
                    char buf[1024]={0};
                    len = recv(clientfd,buf,1024,0);
                    if(len<0){
                        std::cerr<<"fail to recv from server"<<std::endl;
                    }else{
                        nlohmann::json response = nlohmann::json::parse(buf);
                        if(0!=response["error"]){//注册失败
                            std::cerr<<"fail to registe"<<std::endl;
                        }else{//注册成功
                            std::cout<<name<<" registe success ,userID is "<<response["userID"]<<std::endl;
                        }
                    }
                }
                break;
            }
            case 3:{
                close(clientfd);
                exit(0);
                break;
            }
            default:{
                std::cerr<<"invalid input"<<std::endl;
                break;
            }
        }
    }
}

void showCurrentUserData() {
    std::cout<<"==========login user========="<<std::endl;
    std::cout<<"current logic user => id:"<<g_currentUser.id<<" name:"<<g_currentUser.name<<std::endl;
    std::cout<<"==========friend list========="<<std::endl;
    if(!g_currentUserFriendList.empty()){
        for(auto &user : g_currentUserFriendList){
            std::cout<<user.id<<" "<<user.name<<" "<<user.state<<std::endl;
        }
    }
    std::cout<<"==========group list========="<<std::endl;
    if(!g_currentUserGroupList.empty()){
        for(auto& group : g_currentUserGroupList){
            std::cout<<group.id<<" "<<group.name<<" "<<group.desc<<std::endl;
            for(auto groupUser : group.users){
                std::cout << groupUser.user.id<<" "<<groupUser.user.name<<" "<<groupUser.user.state<<" "<<groupUser.role<<std::endl;
            }
        }
    }
    std::cout<<"============================="<<std::endl;
}